﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Animation;

namespace WPFChart
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region Fields 
        public int AnimationDuration = 2;
        public List<Ellipse> EllipseList = new List<Ellipse>();
        public List<Thickness> MarginList = new List<Thickness>() { 
            new Thickness(){ Left=123,Top=148 }, //left 123;148
            new Thickness(){ Left=397,Top=319}, //front 397；319
            new Thickness(){ Left=708,Top=64 }  //right 708；64
        };
        public double OriginWidth = 700;
        public double OriginHeight = 480;
        bool recur = false;

        #endregion
        #region Ctor

        public MainWindow()
        {
            InitializeComponent();

        } 

        #endregion
        #region Ellipse Events

        private void rightEllipse_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            var index = EllipseList.FindIndex(d => d.Name == rightEllipse.Name);

            recur = false;
            if (index == 0)
            {
                recur = true;
                Animate();
            }
            else if (index == 2)
            {
                Animate(); 
            } 
        }

        private void frontEllipse_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            var index = EllipseList.FindIndex(d => d.Name == frontEllipse.Name);

            recur = false;
            if (index == 0)
            {
                recur = true;
                Animate();
            }
            else if (index == 2)
            {
                Animate();
            } 
        }

        private void leftEllipse_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            var index = EllipseList.FindIndex(d => d.Name == leftEllipse.Name);

            recur = false;
            if (index == 0)
            {
                recur = true;
                Animate();
            }
            else if (index == 2)
            {
                Animate();
            } 
        }

        #endregion

        #region Assist Methods

        void DrawLine()
        {
            Point leftEllipseCenter = GetEllipseCenter(leftEllipse);
            Point frontEllipseCenter = GetEllipseCenter(frontEllipse);
            Point rightEllipseCenter = GetEllipseCenter(rightEllipse);
            //leftToFrontLine.X1 = leftEllipseCenter.X;
            //leftToFrontLine.Y1 = leftEllipseCenter.Y;
            //leftToFrontLine.X2 = frontEllipseCenter.X;
            //leftToFrontLine.Y2 = frontEllipseCenter.Y;

            //frontToRightLine.X1 = frontEllipseCenter.X;
            //frontToRightLine.Y1 = frontEllipseCenter.Y;
            //frontToRightLine.X2 = rightEllipseCenter.X;
            //frontToRightLine.Y2 = rightEllipseCenter.Y;

            //rightToLeftLine.X1 = rightEllipseCenter.X;
            //rightToLeftLine.Y1 = rightEllipseCenter.Y;
            //rightToLeftLine.X2 = leftEllipseCenter.X;
            //rightToLeftLine.Y2 = leftEllipseCenter.Y;
        }

        void Animate()
        {
            RemoveChartsEvents();
            var duration = TimeSpan.FromSeconds(AnimationDuration);
            Storyboard storyBoard = new Storyboard();
            storyBoard.Completed += new EventHandler(storyBoard_Completed);
            // right to front
            ThicknessAnimation rightToFrontThicknessAnimation = new ThicknessAnimation();
            rightToFrontThicknessAnimation.From = rightEllipse.Margin;
            rightToFrontThicknessAnimation.To = frontEllipse.Margin;
            rightToFrontThicknessAnimation.Duration = duration;
            storyBoard.Children.Add(rightToFrontThicknessAnimation);
            Storyboard.SetTarget(rightToFrontThicknessAnimation, rightEllipse);
            Storyboard.SetTargetProperty(rightToFrontThicknessAnimation, new PropertyPath(Ellipse.MarginProperty));

            DoubleAnimation rightToFrontWidthDoubleAnimation = new DoubleAnimation();
            rightToFrontWidthDoubleAnimation.Duration = duration;
            rightToFrontWidthDoubleAnimation.From = rightEllipse.Width;
            rightToFrontWidthDoubleAnimation.To = frontEllipse.Width;
            storyBoard.Children.Add(rightToFrontWidthDoubleAnimation);
            Storyboard.SetTarget(rightToFrontWidthDoubleAnimation, rightEllipse);
            Storyboard.SetTargetProperty(rightToFrontWidthDoubleAnimation, new PropertyPath(Ellipse.HeightProperty));

            DoubleAnimation rightToFrontHeightDoubleAnimation = new DoubleAnimation();
            rightToFrontHeightDoubleAnimation.Duration = duration;
            rightToFrontHeightDoubleAnimation.From = rightEllipse.Height;
            rightToFrontHeightDoubleAnimation.To = frontEllipse.Height;
            storyBoard.Children.Add(rightToFrontHeightDoubleAnimation);
            Storyboard.SetTarget(rightToFrontHeightDoubleAnimation, rightEllipse);
            Storyboard.SetTargetProperty(rightToFrontHeightDoubleAnimation, new PropertyPath(Ellipse.WidthProperty));


            // front to left
            ThicknessAnimation frontToLeftThicknessAnimation = new ThicknessAnimation();
            frontToLeftThicknessAnimation.From = frontEllipse.Margin;
            frontToLeftThicknessAnimation.To = leftEllipse.Margin;
            frontToLeftThicknessAnimation.Duration = duration;
            storyBoard.Children.Add(frontToLeftThicknessAnimation);
            Storyboard.SetTarget(frontToLeftThicknessAnimation, frontEllipse);
            Storyboard.SetTargetProperty(frontToLeftThicknessAnimation, new PropertyPath(Ellipse.MarginProperty));

            DoubleAnimation frontToLeftWidthDoubleAnimation = new DoubleAnimation();
            frontToLeftWidthDoubleAnimation.Duration = duration;
            frontToLeftWidthDoubleAnimation.From = frontEllipse.Width;
            frontToLeftWidthDoubleAnimation.To = leftEllipse.Width;
            storyBoard.Children.Add(frontToLeftWidthDoubleAnimation);
            Storyboard.SetTarget(frontToLeftWidthDoubleAnimation, frontEllipse);
            Storyboard.SetTargetProperty(frontToLeftWidthDoubleAnimation, new PropertyPath(Ellipse.HeightProperty));

            DoubleAnimation frontToLeftHeightDoubleAnimation = new DoubleAnimation();
            frontToLeftHeightDoubleAnimation.Duration = duration;
            frontToLeftHeightDoubleAnimation.From = frontEllipse.Height;
            frontToLeftHeightDoubleAnimation.To = leftEllipse.Height;
            storyBoard.Children.Add(frontToLeftHeightDoubleAnimation);
            Storyboard.SetTarget(frontToLeftHeightDoubleAnimation, frontEllipse);
            Storyboard.SetTargetProperty(frontToLeftHeightDoubleAnimation, new PropertyPath(Ellipse.WidthProperty));


            // left to right
            ThicknessAnimation leftToRightThicknessAnimation = new ThicknessAnimation();
            leftToRightThicknessAnimation.From = leftEllipse.Margin;
            leftToRightThicknessAnimation.To = rightEllipse.Margin;
            leftToRightThicknessAnimation.Duration = duration;
            storyBoard.Children.Add(leftToRightThicknessAnimation);
            Storyboard.SetTarget(leftToRightThicknessAnimation, leftEllipse);
            Storyboard.SetTargetProperty(leftToRightThicknessAnimation, new PropertyPath(Ellipse.MarginProperty));

            DoubleAnimation leftToRightWidthDoubleAnimation = new DoubleAnimation();
            leftToRightWidthDoubleAnimation.Duration = duration;
            leftToRightWidthDoubleAnimation.From = leftEllipse.Width;
            leftToRightWidthDoubleAnimation.To = rightEllipse.Width;
            storyBoard.Children.Add(leftToRightWidthDoubleAnimation);
            Storyboard.SetTarget(leftToRightWidthDoubleAnimation, leftEllipse);
            Storyboard.SetTargetProperty(leftToRightWidthDoubleAnimation, new PropertyPath(Ellipse.HeightProperty));

            DoubleAnimation leftToRightHeightDoubleAnimation = new DoubleAnimation();
            leftToRightHeightDoubleAnimation.Duration = duration;
            leftToRightHeightDoubleAnimation.From = leftEllipse.Height;
            leftToRightHeightDoubleAnimation.To = rightEllipse.Height;
            storyBoard.Children.Add(leftToRightHeightDoubleAnimation);
            Storyboard.SetTarget(leftToRightHeightDoubleAnimation, leftEllipse);
            Storyboard.SetTargetProperty(leftToRightHeightDoubleAnimation, new PropertyPath(Ellipse.WidthProperty));

            storyBoard.Begin();

        }

        void storyBoard_Completed(object sender, EventArgs e)
        {
            var ellipses = new List<Ellipse>();
            ellipses.AddRange(EllipseList.ToArray());
            EllipseList.Clear();
            EllipseList.Add(ellipses[1]);
            EllipseList.Add(ellipses[2]);
            EllipseList.Add(ellipses[0]);
            if (recur)
            {
                recur = false;
                Animate();
            }
            else 
            {
                AddChartsEvents();
            }
        }
         

        Point GetEllipseCenter(Ellipse ellipse)
        {
            return new Point(ellipse.Margin.Left + ellipse.Width / 2, ellipse.Margin.Top + ellipse.Height / 2);
        }

        protected void RepositionChart(Size size)
        {
            for (int i = 0; i < EllipseList.Count; i++)
            {
                var width = EllipseList[i].Width;
                var height = EllipseList[i].Height;
                var margin = new Thickness()
                {
                    Left = (MarginList[i].Left + width / 2) * size.Width / OriginWidth - width / 2,
                    Top = (MarginList[i].Top + height / 2) * size.Height / OriginHeight - height / 2
                };
                EllipseList[i].SetCurrentValue(Ellipse.MarginProperty, margin);
                //EllipseList[i].Margin = margin;
            }
        }

        protected void AddChartsEvents()
        {
            leftEllipse.MouseLeftButtonUp += new MouseButtonEventHandler(leftEllipse_MouseLeftButtonUp);
            frontEllipse.MouseLeftButtonUp += new MouseButtonEventHandler(frontEllipse_MouseLeftButtonUp);
            rightEllipse.MouseLeftButtonUp += new MouseButtonEventHandler(rightEllipse_MouseLeftButtonUp);
            this.SizeChanged += new SizeChangedEventHandler(MainWindow_SizeChanged);
            //this.ResizeMode = System.Windows.ResizeMode.CanResize;
        }

        protected void RemoveChartsEvents()
        {
            leftEllipse.MouseLeftButtonUp -= new MouseButtonEventHandler(leftEllipse_MouseLeftButtonUp);
            frontEllipse.MouseLeftButtonUp -= new MouseButtonEventHandler(frontEllipse_MouseLeftButtonUp);
            rightEllipse.MouseLeftButtonUp -= new MouseButtonEventHandler(rightEllipse_MouseLeftButtonUp);
            this.SizeChanged -= new SizeChangedEventHandler(MainWindow_SizeChanged);
            //this.ResizeMode = System.Windows.ResizeMode.NoResize;
        }

        #endregion

        #region Load

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            EllipseList = new List<Ellipse>() { 
                leftEllipse,frontEllipse,rightEllipse
            };
            MarginList = new List<Thickness>() { 
                leftEllipse.Margin,frontEllipse.Margin,rightEllipse.Margin
            };
            OriginHeight = this.Height;
            OriginWidth = this.Width;
            RepositionChart(new Size() { Height = OriginHeight, Width = OriginWidth });
            AddChartsEvents();
        }

        #endregion

        private void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            RepositionChart(e.NewSize);
        }

    }
}
